﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using CodeCube.Common;
using CodeCube.Extensions;
using CodeCube.Service.DtoModel;
using CodeCube.Service.Interfaces;
using CodeCube.Service.Model;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ParrotBox.Api;
using static CodeCube.Service.DtoModel.SysMenuDto;

namespace CodeCube.Api.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Produces("application/json")]
    [ApiExplorerSettings(GroupName = "CodeCube")]
    public class AuthorizeController : ControllerBase
    {
        private readonly ILoginOperateService _LoginOperateService;
        private readonly IUserInfoService _UserInfoService;
        /// <summary>
        /// 初始化注入
        /// </summary>
        /// <param name="loginOperateService"></param>
        /// <param name="userInfoService"></param>
        public AuthorizeController(
            ILoginOperateService loginOperateService,
            IUserInfoService userInfoService)
        {
            _LoginOperateService = loginOperateService;
            _UserInfoService = userInfoService;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="Account">账号</param>
        /// <param name="Password">密码</param>
        /// <param name="VerificationCode">验证码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<UserAccountModel>> Login(string Account,string Password,string VerificationCode)
        {
            var res = await _LoginOperateService.LoginAsync(Account, Password);
            //获得用户登录限制次数
            var configLoginCount = Convert.ToInt32(ConfigExtensions.Configuration[KeyHelper.LOGINCOUNT]);
            //获得登录次数和过期时间
            var loginConfig = MemoryCacheService.Default.GetCache<SysAdminLoginConfig>(KeyHelper.LOGINCOUNT) ?? new SysAdminLoginConfig();
            if (loginConfig.Count != 0 && loginConfig.DelayMinute != null)
            {
                //说明存在过期时间，需要判断
                if (DateTime.Now <= loginConfig.DelayMinute)
                {
                    res.message = "您的登录以超过设定次数，请稍后再次登录~";
                    return res;
                }
                else
                {
                    //已经过了登录的预设时间，重置登录配置参数
                    loginConfig.Count = 0;
                    loginConfig.DelayMinute = null;
                }
            }
            if (res.success)
            {
                var user = await _UserInfoService.GetModelAsync(res.data.Guid);
                var menuSaveType = ConfigExtensions.Configuration[KeyHelper.LOGINAUTHORIZE];
                if (menuSaveType == "Redis")
                {
                    RedisHelper.Set(KeyHelper.ADMINMENU + "_" + res.data.Guid, _LoginOperateService.GetMenuItemListAsync(res.data.Guid).Result);
                }else{ 
                    MemoryCacheService.Default.SetCache(KeyHelper.ADMINMENU + "_" + res.data.Guid, _LoginOperateService.GetMenuItemListAsync(res.data.Guid).Result); 
                }
                var identity = new ClaimsPrincipal(
                    new ClaimsIdentity(new[]
                        { 
                        new Claim(ClaimTypes.Sid,user.data.Guid),
                        new Claim(ClaimTypes.Role,user.data.RoleGuid),
                        new Claim(ClaimTypes.Name,user.data.NickName),
                        new Claim(ClaimTypes.Thumbprint,user.data.Avatar),
                        new Claim(ClaimTypes.WindowsAccountName,user.data.Account),
                        new Claim(ClaimTypes.UserData,user.data.LastLoginDT.ToString())
                    },CookieAuthenticationDefaults.AuthenticationScheme)
                    );
                //如果保存用户类型是Session，则默认设置cookie退出浏览器 清空
                if (ConfigExtensions.Configuration[KeyHelper.LOGINSAVEUSER] == "Session")
                {
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, identity, new AuthenticationProperties
                    {
                        AllowRefresh = false
                    });
                }
                else
                {
                    //根据配置保存浏览器用户信息，小时单位
                    var hours = int.Parse(ConfigExtensions.Configuration[KeyHelper.LOGINCOOKIEEXPIRES]);
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, identity, new AuthenticationProperties
                    {
                        ExpiresUtc = DateTime.UtcNow.AddHours(hours),
                        IsPersistent = true,
                        AllowRefresh = false
                    });
                }
            }
            return res;
        }
        /// <summary>
        /// 获取权限内菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet, ApiAuthorize(Modules = "Sys", Methods = "Look", LogType = LogEnum.LOOK)]
        public async Task<List<SysMenuDto>> GetMenu()
        {
            var tokenHeader = HttpContext.Request.Headers["Authorization"];
            tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
            var tm = JwtHelper.SerializeJWT(tokenHeader);
            var mlist = await _LoginOperateService.GetMenuItemListAsync(tm.Uid);
            return await _LoginOperateService.GetMenuTreeAsync("root", mlist);
        }
    }
}